
#include "ls_common.h"
#include "bflb_spi.h"
#include "bflb_dma.h"
#include "board.h"
#include "ls_spi.h"

#define DBG_TAG "LS_SPI"
#include "ls_trace_common.h"


#define SPI_FRQ                 10 // bus frequency.

//
static  struct bflb_device_s *spi0;
static  struct bflb_device_s *gpio;

static uint32_t spi_tc_done_count = 0;


/// @brief 
/// @param irq 
/// @param arg 
void spi_isr(int irq, void *arg)
{
    uint32_t intstatus = bflb_spi_get_intstatus(spi0);
    if (intstatus & SPI_INTSTS_TC) {
        bflb_spi_int_clear(spi0, SPI_INTCLR_TC);
        spi_tc_done_count++;
        // LS_TRACE_DEBUG("tc done:%d",spi_tc_done_count); 
    }


    if (intstatus & SPI_INTSTS_TX_FIFO) {
        LS_TRACE_DEBUG("tx fifo");
        bflb_spi_int_clear(spi0, SPI_INTSTS_TX_FIFO);
    }

    if (intstatus & SPI_INTSTS_RX_FIFO) {
        LS_TRACE_DEBUG("rx fifo");
        bflb_spi_int_clear(spi0, SPI_INTSTS_RX_FIFO);
    }
}




/// @brief 
void ls_spi_init()
{
    //gpio初始化
    LS_TRACE_DEBUG("ls_spi_init");
    board_spi0_gpio_init();
    gpio = bflb_device_get_by_name("gpio");
    //spi 初始化
    struct bflb_spi_config_s spi_cfg = {
        .freq = SPI_FRQ * 1000 * 1000,
        .role = SPI_ROLE_MASTER,
        .mode = SPI_MODE1,
        .data_width = SPI_DATA_WIDTH_16BIT,
        .bit_order = SPI_BIT_MSB,
        .byte_order = SPI_BYTE_MSB,
        .tx_fifo_threshold = 0,
        .rx_fifo_threshold = 0,
    };


    //
    spi0 = bflb_device_get_by_name("spi0");
    bflb_spi_init(spi0, &spi_cfg);
    //
    bflb_spi_tcint_mask(spi0, false);
    
    bflb_irq_attach(spi0->irq_num, spi_isr, NULL);
    bflb_irq_enable(spi0->irq_num);
    //
    bflb_spi_feature_control(spi0, SPI_CMD_SET_CS_INTERVAL,0);
}   




/// @brief 
/// @param tx_buf 
/// @param rx_buf 
/// @param len 
void spi_poll_u8(const unsigned char *tx_buf,unsigned char *rx_buf,unsigned int len) 
{
//    LS_TRACE_ERROR("spi poll exchange  len %d",len);
   
   /* set data width */
   bflb_spi_poll_exchange(spi0,tx_buf,rx_buf,len);
}




/// @brief 
/// @param value 
void spi_select_cs(uint8_t value)
{
    if(value)
    {
       bflb_gpio_reset(gpio,GPIO_PIN_16);
    }
    else
    {
       bflb_gpio_set(gpio,GPIO_PIN_16);
    }
}